package com.ecar.api.service.order.impl;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.text.StyledEditorKit.BoldAction;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ecar.api.rest.AbstractResource;
import com.ecar.api.service.common.NotifyService;
import com.ecar.api.service.driver.DriverService;
import com.ecar.api.service.order.OrderService;
import com.ecar.api.support.dto.Constants;
import com.ecar.api.support.dto.order.DriverWilddogDto;
import com.ecar.api.support.dto.order.PassengerWilddogDto;
import com.ecar.api.support.util.DateUtil;
import com.ecar.api.support.util.GaoDeMapUtil;
import com.ecar.api.support.util.LatLonUtil;
import com.ecar.api.support.util.Props;
import com.ecar.api.support.util.Redis;
import com.ecar.api.support.util.UserUtil;
import com.ecar.api.support.util.UuidUtils;
import com.ecar.api.support.util.WilddogUtil;
import com.ecar.common.dto.DataBean;
import com.ecar.common.dto.DataBeanEcar;
import com.ecar.common.dto.Pager;
import com.ecar.common.util.BeanUtils;
import com.ecar.common.util.DataValidateUtil;
import com.ecar.common.util.JSONUtil;
import com.ecar.common.util.StringUtil;
import com.ecar.core.common.entity.User;
import com.ecar.core.driver.dao.CarMapper;
import com.ecar.core.driver.dao.DriverMapper;
import com.ecar.core.driver.dao.ModelSetMapper;
import com.ecar.core.driver.entity.Car;
import com.ecar.core.driver.entity.Driver;
import com.ecar.core.order.dao.OrderMapper;
import com.ecar.core.order.dao.OrderPriceDetailMapper;
import com.ecar.core.order.entity.Order;
import com.ecar.core.order.entity.OrderPriceDetail;
import com.ecar.core.passenger.dao.InvoiceMapper;
import com.ecar.core.passenger.entity.Invoice;
import com.wilddog.client.DataSnapshot;
import com.wilddog.client.SyncError;
import com.wilddog.client.SyncReference;
import com.wilddog.client.ValueEventListener;

import net.sf.json.JSONObject;

@Service
@Transactional
public class OrderServiceImpl implements OrderService {

	static Logger log = LoggerFactory.getLogger(AbstractResource.class);

	@Autowired
	OrderPriceDetailMapper orderPriceDetailMapper;
	
	@Autowired
	OrderMapper orderMapper;

	@Autowired
	DriverMapper driverMapper;

	@Autowired
	CarMapper carMapper;

	@Autowired
	ModelSetMapper modelSetMapper;

	@Autowired
	InvoiceMapper invoiceMapper;
	
	@Autowired
	NotifyService notifyService;
	
	@Autowired
	DriverService driverService;
	
	@Override
	public List<Order> selectTodayCarpool() {
		// TODO Auto-generated method stub
		return orderMapper.selectTodayCarpool();
	}
	
	@Override
	public List<Order> selectWorkingOrderToday() {
		// TODO Auto-generated method stub
		return orderMapper.selectWorkingOrderToday();
	}
	
	@Override
	public List<Order> selectTodayOrder() {
		return orderMapper.selectTodayOrder();
	}
	
	@Override
	public int updateByOrderNumSelective(Order record) {
		return orderMapper.updateByOrderNumSelective(record);
	}
	
	@Override
	public List<Order> selectAppointmentCarpool() {
		return orderMapper.selectAppointmentCarpool();
	}
	
	@Override
	public List<Order> overTimeOrder() {
		return orderMapper.overTimeOrder();
	}
	
	@Override
	public int countUnendOrderByDriverId(String driverId){
		return orderMapper.countUnendOrderByDriverId(driverId);
	}

	@Override
	public int updateByPrimaryKeySelective(Order record) {
		return orderMapper.updateByPrimaryKeySelective(record);
	}
	
	@Override
	public List<Order> selectCarpoolParentOrder() {
		return orderMapper.selectCarpoolParentOrder();
	}
	
	@Override
	public int queryOrderCountByDriverId(String driverId) {
		return orderMapper.queryOrderCountByDriverId(driverId);
	}

	@Override
	public Double queryTotalPrice(String driverId) {
		return orderMapper.queryTotalPrice(driverId);
	}
	
	@Override
	public List<Order> selectCarpoolOrderBySeat(int seat){
		return orderMapper.selectCarpoolOrderBySeat(seat);
	}
	
	@Override
	public List<Order> selectF2FParentOrder(String driverId) {
		// TODO Auto-generated method stub
		return orderMapper.selectF2FParentOrder(driverId);
	}
	/**
	 * 获取需要改派的订单
	 */
	@Override
	public List<Order> selectAppointmentToNowOrder() {
		// TODO Auto-generated method stub
		return orderMapper.selectAppointmentToNowOrder();
	}
	/**
	 * 获取预约订单
	 */
	@Override
	public List<Order> selectAppointmentOrder() {
		return orderMapper.selectAppointmentOrder();
	}
	/**
	 * 获取未派发的订单
	 */
	@Override
	public List<Order> selectUnsendOrder() {
		return orderMapper.selectUnsendOrder();
	}

	/**
	 * 抢单
	 * @param order
	 * @return
	 */
	@Override
	public DataBean grabOrder(Order order){
		int i=0;
		synchronized (order) {
			Order temp=orderMapper.selectByOrderNum(order.getOrderNum());
			Driver driver=driverMapper.selectByPrimaryKey(order.getDriverId());
			if(driver==null){
				log.info("司机不存在");
				return new DataBean(400,new JSONObject(),"司机id不存在");
			}
			if(temp==null){
				log.info("订单不存在");
				return new DataBean(400,new JSONObject(),"订单不存在");
			}
			if(temp.getDriverId()!=null || temp.getOrderStatus()==1){
				log.info("订单{}已被抢",order.getOrderNum());
				return new DataBean(201,new JSONObject(),"你慢了一步");
			}
			Order result=new Order();
			result.setId(temp.getId());
			result.setDriverId(order.getDriverId());
			result.setReceiveTime(new Date());
			result.setOrderStatus(3);
			i=orderMapper.updateByPrimaryKeySelective(result);
			if(i==1){
				log.info("预约单写入野狗");
				temp.setOrderStatus(3);
				HashMap<String, Object> passengerMap=sendToPassenger(temp, driver);
				WilddogUtil.sendOrderToPassenger(order.getOrderNum(), passengerMap);
				
				return new DataBean(200,new JSONObject(),"抢单成功");
			}else{
				return new DataBean(500,new JSONObject(),"抢单失败");
			}
		}
	}

	@Override
	public int sendOrder(Order order) {
		//orderType:(1:接机2:送机3:快车即时4:快车预约)
		switch (order.getOrderType()){
		case 1:
		case 4:
		case 2:
			sendAppointmentOrder(order.getOrderNum(),"");
			break;
		case 3:
		case 5:
			sendNowOrder(order.getOrderNum());
			break;
		default:
			break;
		}


		return 200;
	}
	/**
	 * 
	 * 发布预约订单
	 * @author fire
	 * @param orderNum
	 * 200成功
	 * 401订单状态错误
	 * 402未找到合适司机
	 * 403移除订单失败
	 * 404订单无响应
	 * 400订单已派单
	 */
	private void sendAppointmentOrder(String orderNum,final String token) {
		//发单次数验证
		String key = Redis.K.ORDER_SEND.to(orderNum);
		final int count = Integer.valueOf(Redis.c.get(key));
		log.info("发单{}次数{}",orderNum,count);
		Redis.c.del(key);
		int EXPIRE = 1800;
		Redis.c.setex(Redis.K.ORDER_SEND.to(orderNum), EXPIRE, (count+1)+"");
		final Order order=orderMapper.selectByOrderNum(orderNum);
		if(order.getOrderStatus()!=2){
			log.info("订单状态错误");
			return;
		}
		if(order.getDriverId()!=null && !order.getDriverId().equals("")){
			log.info("该订单已处于接单状态");
			return;
		}
		double size=0.0;
		switch(count){
		case 1:
			size=3000;
			break;
		case 2:
			size=5000;
			break;
		default:
			/*size=35000;*/
			break;
		}
		//获取订单的预约时间
		Date currentTime=order.getStartTime();
		//获取为预约的接单模式的司机
		final List<Driver> temp = driverMapper.selectDriverBetweenTime(currentTime);
		List<Driver> drivers=new ArrayList<Driver>();
		for(Driver driver:temp){
			double distance=-1;
			countDistance(driver.getId(),order);
			String a = Redis.K.ORDER_DISTANCE.to(driver.getId(),orderNum);
			//当redis里有数据是继续
			String c=null;
			while(StringUtil.isEmpty(c)||c.equals("0")){
				c=Redis.c.get(a);
			}
			log.info("距离"+c);
			distance=Double.valueOf(c).doubleValue();
			if(distance<0){
				/*log.info("司机{}野狗数据有误，司机下线",driver.getId());
				driverService.stopGetOrder(driver.getId());*/
				continue;
			}
			if(distance<size||size==0.0){
				drivers.add(driver);
			}
		}
		log.info("共找到{}个司机",drivers.size());
		if(drivers.size()==0){
			log.info("未找到任何司机可接单");
			return;
		}
		for(final Driver driver:drivers){
			WilddogUtil.getPassengerRef("WilddogLocation/order").addListenerForSingleValueEvent(new ValueEventListener() {
				@Override
				public void onCancelled(SyncError arg0) {
				}
				@Override
				public void onDataChange(DataSnapshot dataSnapshot) {
					if(!dataSnapshot.child(driver.getId()).hasChild("appointment")){
						//写入司机野狗的数据
						//SyncReference driverRef = WilddogUtil.getDriverRef("WilddogLocation");
						HashMap<String, Object> driverMap=sendToDriver(order, driver,2, token);
						if(driverMap==null){
							return;
						}
						log.info("写入野狗");
						WilddogUtil.sendAppointmentOrderToDriver(driver.getId(), driverMap);
					}else{
						log.info("司机已发单");
					}
				}
			});
			
		}
	}
	//初始写入野狗乘客端订单
	@Override
	public HashMap<String, Object> sendToPassengerTemp(Order order){
		log.info("写入乘客端{}数据"+order.getOrderNum());
		PassengerWilddogDto passengerWilddogDto=new PassengerWilddogDto();
		//复制了orderNum,orderType,driverId,
		BeanUtils.copySolidProperties(order, passengerWilddogDto);
		passengerWilddogDto.setDriverId("");
		passengerWilddogDto.setRates(0.0);
		passengerWilddogDto.setRated(0);
		passengerWilddogDto.setDriverPhone("");
		passengerWilddogDto.setAvatar("");
		passengerWilddogDto.setDriverName("");
		passengerWilddogDto.setNumberPlate("");
		passengerWilddogDto.setModel("");
		passengerWilddogDto.setCreateTime(DateUtil.dateToMS(order.getCreateTime()));
		passengerWilddogDto.setOrderStatus(order.getOrderStatus());
		Map<String, Object> pmap=DataValidateUtil.objectToMap(DataValidateUtil.parseNull(passengerWilddogDto));
		HashMap<String, Object> tempMap = new HashMap<String, Object>();
		tempMap.put("resource",pmap);
		
		return tempMap;
	}
	
	@Override
	public HashMap<String, Object> sendToPassenger(Order order,Driver driver){
		log.info("写入乘客端{}数据"+order.getOrderNum());
		//乘客端需要的司机资料
		PassengerWilddogDto passengerWilddogDto=new PassengerWilddogDto();
		BeanUtils.copySolidProperties(order, passengerWilddogDto);
		passengerWilddogDto.setDriverId(driver.getId());
		passengerWilddogDto.setCreateTime(DateUtil.dateToMS(order.getCreateTime()));
		passengerWilddogDto.setReceiveTime(DateUtil.dateToMS(new Date()));
		passengerWilddogDto.setRates(driver.getRates());
		passengerWilddogDto.setDriverPhone(driver.getPhone());
		passengerWilddogDto.setAvatar(driver.getAvatar());
		passengerWilddogDto.setDriverName(driver.getName());
		passengerWilddogDto.setOrderStatus(order.getOrderStatus());
		//计算司机总接单数
		int rated=orderMapper.countByDriverId(driver.getId());
		passengerWilddogDto.setRated(rated);
		Car car=carMapper.selectByDriverId(driver.getId());
		if(car==null){
			log.info("该司机没有车");
			return null;
		}
		BeanUtils.copySolidProperties(car, passengerWilddogDto);
		Map<String, Object> pmap=DataValidateUtil.objectToMap(DataValidateUtil.parseNull(passengerWilddogDto));

		HashMap<String, Object> tempMap = new HashMap<String, Object>();
		tempMap.put("resource",pmap);
		return tempMap;
	}
	
	@Override
	public HashMap<String, Object> sendToDriver(Order order,Driver driver,Integer type,String token){
		log.info("写入司机端{}数据"+driver.getId());
		//司机端需要的乘客资料
		DriverWilddogDto driverWilddogDto=new DriverWilddogDto();
		driverWilddogDto.setCarpool(order.getOrderNum());
		BeanUtils.copySolidProperties(order, driverWilddogDto);
		//获取乘客的名字
		if(order.getOrderType()!=6){
			User user=UserUtil.getUser(order.getPassengerId(), token);
			if(user==null){
				log.info("未找到乘客");
				return null;
			}
			driverWilddogDto.setPassengerName(user.getName());
			driverWilddogDto.setPhone(user.getPhone());
			
		}else{
			driverWilddogDto.setPassengerName(order.getPassengerPhone());
			driverWilddogDto.setPhone(order.getPassengerPhone());
		}
		//司机的接单模式
		driverWilddogDto.setOrderModel(1);
		if(StringUtil.isNotEmpty(order.getCustomerName())){
			driverWilddogDto.setPassengerName(order.getCustomerName());
			driverWilddogDto.setPhone(order.getCustomerPhone());
		}
		if(type==1){
			driverWilddogDto.setOrderStatus(3);
		}
		driverWilddogDto.setCreateTime(DateUtil.dateToMS(order.getStartTime()));
		Map<String, Object> map=DataValidateUtil.objectToMap(DataValidateUtil.parseNull(driverWilddogDto));
		HashMap<String, Object> tempMap = new HashMap<String, Object>();
		tempMap.put(order.getOrderNum(), map);
		return tempMap;
	}
	
	@Override
	public boolean send(Order order,Driver driver){
		log.info("派单{}"+order.getOrderNum());

		//写入司机野狗的数据
		//写入乘客野狗数据
		order.setOrderStatus(3);
		HashMap<String, Object> driverMap=sendToDriver(order, driver,1,"");
		if(driverMap==null){
			return false;
		}
		HashMap<String, Object> passengerMap = sendToPassenger(order, driver);
		if(passengerMap==null){
			return false;
		}
		if(order.getOrderType()==5){
			WilddogUtil.sendCarpoolOrderToDriver(driver.getId(), driverMap);
		}else if(order.getOrderType()==3){
			WilddogUtil.sendNowOrderToDriver(driver.getId(), driverMap);
		}else{
			String content = Props.getValue("sms.msg.appointment.driver2");
			content = MessageFormat.format(content, DateUtil.parseDateToString(order.getPlanTime(),"yyyy-MM-dd HH:mm:ss"),order.getStartAddress(),order.getDesAddress(),order.getPassengerPhone());
			notifyService.sendSingleSMS(driver.getPhone(), content);
		}
		WilddogUtil.sendOrderToPassenger(order.getOrderNum(),passengerMap);
		return true;
		
	}
	private void updateOrder(Driver driver,Order order){
		Order result=new Order();
		BeanUtils.copyProperties(order, result);
		result.setId(order.getId());
		result.setReceiveTime(new Date());
		result.setDriverId(driver.getId());
		result.setOrderStatus(order.getOrderStatus());
		result.setOrderStatus(3);
		Car car=carMapper.selectByDriverId(driver.getId());
		result.setVehicleId(car.getId());
		//修改司机的接单状态
		if(order.getOrderType()==3){
			log.info("派单完成，修改司机{}状态",driver.getId());
			modelSetMapper.stopGetOrder(driver.getId());
		}
		
		orderMapper.updateByPrimaryKeySelective(result);
	}
	private void sort(List<Map.Entry<Driver, Double>> list){
		Collections.sort(list, new Comparator<Map.Entry<Driver, Double>>() {  
			//降序排序  
			@Override  
			public int compare(Entry<Driver, Double> o1, Entry<Driver, Double> o2) {  
				//return o1.getValue().compareTo(o2.getValue());  
				return o2.getValue().compareTo(o1.getValue());  
			}  
		});  
	}

	/**
	 * 实时派单
	 * @author fire
	 * @param 
	 * 
	 * 
	 */
	@Override
	public void sendNowOrder(String orderNum) {
		try {
			log.info("实时强制派单"+orderNum);
			//前端传个订单号
			final Order order=orderMapper.selectByOrderNum(orderNum);
			//验证订单状态  1:订单取消2:等待接单3:司机已接单4:到达上车点5:开始行程6:结束行程
			if(order.getOrderStatus()!=2){
				log.info("订单状态有误");
				return;
			}
			//查询所有可以接实时单的司机
			final List<Driver> drivers = driverMapper.selectDriverByOrderModelAndModelStatus();
			if(drivers.size()==0){
				log.info("未找到任何司机可接单");
				return;
			}
			log.info("找到了{}司机",drivers.size());
			Map<Driver, Double> map=new HashMap<Driver, Double>();
			Driver driver =new Driver();
			boolean flag=true;
			for(int i=0;i<drivers.size();i++){
				
				/**
				 * 18.1.6
				 * 预约单，添加新的限制
				 * 判断司机身上是否存在该强制派发的订单半小时内的订单
				 */
				if(order.getOrderType()==1 || order.getOrderType()==2 || order.getOrderType()==4){
					Date planTime =order.getPlanTime();
					if(orderMapper.countHalfHourAppointmentOrderByDriverId(drivers.get(i).getId(),planTime)>0){
						log.info("预约单，该司机{}身上有临近预约时间的订单",drivers.get(i).getId());
						continue;
					}
				}
				
				double distance=-1;
				countDistance(drivers.get(i).getId(),order);
				String key = Redis.K.ORDER_DISTANCE.to(drivers.get(i).getId(),order.getOrderNum());
				//当redis里有数据是继续
				
				String c=null;
				while(StringUtil.isEmpty(c)||c.equals("0")){
					c=Redis.c.get(key);
				}
				/*log.info("距离"+c);
				while(c==null){
					if(Redis.c.exists(key)){
						c=Redis.c.get(key);
					}
				}*/
				log.info("距离"+c);
				distance=Double.valueOf(c).doubleValue();
				if(distance == -1.0 || distance == -2.0){
					/*log.info("司机{}野狗数据有误，司机下线",drivers.get(i).getId());
					driverService.stopGetOrder(drivers.get(i).getId());*/
					continue;
				}
				if(distance<=1000.0){
					log.info("司机{}距离低于1000米,直接派单",drivers.get(i).getId());
					//派单
					//不需要再修改driver
					driver= drivers.get(i);
					order.setOrderStatus(3);
					if(!send(order, driver)){
						log.info("派单失败，重新开始派单");
						continue;
					};
					
					//判断订单是否为拼车单，如果是拼车单，就将座位数添加到redis里
					if(order.getOrderType()==5){
						//已派出的拼车单父订单为其本身
						Car car=carMapper.selectByDriverId(driver.getId());
						Integer useSeat=order.getUseSeats();
						Integer leftSeat=0;
						if(car.getSeatType()==1){
							//5座
							leftSeat=4-useSeat;
						}else if(car.getSeatType()==2){
							//7座
							leftSeat=6-useSeat;
						}
						order.setParentOrder(order.getOrderNum());
						int EXPIRE = 7200;
						Redis.c.setex(Redis.K.ORDER_CARPOOL.to(order.getOrderNum()), EXPIRE, String.valueOf(leftSeat));
						log.info("派单完成，修改司机{}状态",driver.getId());
						modelSetMapper.stopGetOrder(driver.getId());
						//下了拼车单后写入起点位置
						//WilddogUtil.sendMessage(WilddogUtil.getDriverRef("WilddogLocation/order"), driver.getId(), carpoolMap);
					}
					if(order.getOrderType()==3 || order.getOrderType()==5){
						List<Order> tempList=new ArrayList<Order>();
						tempList.add(order);
						HashMap<String, Object> carpoolMap=new HashMap<String, Object>();
						carpoolMap.put("carpool", order.getOrderNum());
						WilddogUtil.sendSortDriver(tempList,driver.getId(), carpoolMap);
					}
					updateOrder(driver, order);
					//已经派单就退出循环
					flag=false;
					return;
				}
				map.put(drivers.get(i), Double.valueOf(distance));
			}
			if(flag){
				log.info("所有司机已筛查完成");
				List<Entry<Driver, Double>> list = new ArrayList<Entry<Driver, Double>>(map.entrySet());
				if(list.size()==0){
					log.info("没有司机可以派单");
				}else{
					sort(list);
					driver= list.get(list.size()-1).getKey();
					send(order, driver);
					//判断订单是否为拼车单，如果是拼车单，就将座位数添加到redis里
					if(order.getOrderType()==5){
						//已派出的拼车单父订单为其本身
						Car car=carMapper.selectByDriverId(driver.getId());
						Integer useSeat=order.getUseSeats();
						Integer leftSeat=0;
						if(car.getSeatType()==1){
							//5座
							leftSeat=4-useSeat;
						}else if(car.getSeatType()==2){
							//7座
							leftSeat=6-useSeat;
						}
						order.setParentOrder(order.getOrderNum());
						int EXPIRE = 7200;
						Redis.c.setex(Redis.K.ORDER_CARPOOL.to(order.getOrderNum()), EXPIRE, String.valueOf(leftSeat));
						log.info("派单完成，修改司机{}状态",driver.getId());
						modelSetMapper.stopGetOrder(driver.getId());
						//下了拼车单后写入起点位置
						//WilddogUtil.sendMessage(WilddogUtil.getDriverRef("WilddogLocation/order"), driver.getId(), carpoolMap);
					}
					if(order.getOrderType()==3 || order.getOrderType()==5){
						List<Order> tempList=new ArrayList<Order>();
						tempList.add(order);
						HashMap<String, Object> carpoolMap=new HashMap<String, Object>();
						carpoolMap.put("carpool", order.getOrderNum());
						WilddogUtil.sendSortDriver(tempList,driver.getId(), carpoolMap);
					}
					updateOrder(driver, order);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.info("强制派单异常");
		}
	}
	/**
	 * 根据司机id和订单开始地点算距离
	 * distance为0时为初始化，-1时为野狗无该司机，-2为野狗司机为更新
	 * @author fire
	 */
	private static void countDistance(final String driverId,final Order order){
		SyncReference driverRef=WilddogUtil.getDriverRef("WilddogLocation/map");

		//监听一次
		driverRef.addListenerForSingleValueEvent(new ValueEventListener() {

			@Override
			public void onDataChange(DataSnapshot dataSnapshot) {
				double distance=-1;
				int EXPIRE = 45;
				Redis.c.setex(Redis.K.ORDER_DISTANCE.to(driverId,order.getOrderNum()), EXPIRE, String.valueOf(0));
				boolean a=dataSnapshot.hasChild(driverId);
				if(!a){
					//如果野狗快照中没有该司机的的ID的时候直接不进行筛选
					log.info("野狗快照中没有该司机"+driverId);
					Redis.c.setex(Redis.K.ORDER_DISTANCE.to(driverId,order.getOrderNum()), EXPIRE, String.valueOf(-1));
					return;
				}
				long time=(long) dataSnapshot.child(driverId).child("timestamp").getValue();
				log.info("获取到野狗数据");
				long lt = new Long(time);
				Date timeDriver = new Date(lt);
				log.info("当前时间"+DateUtil.getCurDateTime());
				log.info("该司机 {}上次更新时间"+DateUtil.parseDateToString(timeDriver," yyyy-MM-dd HH:mm:ss"),driverId);
				Date timeNow=DateUtil.afterNMinsDateToDate(timeDriver, "5");
				if(new Date().after(timeNow)){
					//该时刻已经是司机半个小时未更新地址
					log.info("该司机{}已经5分钟未更新地址",driverId);
					Redis.c.setex(Redis.K.ORDER_DISTANCE.to(driverId,order.getOrderNum()), EXPIRE, String.valueOf(-2));
					return;
				}
				log.info("开始获取订单的出发地点");
				String position=order.getStartLocation();
				String[] p = position.split(":");
				double d1=Double.valueOf(p[0]);
				double d2=Double.valueOf(p[1]);
				log.info("乘客的具体位置经度{}纬度{}",d1,d2);
				//获取司机地址
				double x=(double) dataSnapshot.child(driverId).child("location").child("0").getValue();
				double y=(double) dataSnapshot.child(driverId).child("location").child("1").getValue();
				log.info("司机的具体位置经度{}纬度{}",x,y);
				//获取两者间的距离
				
				distance=GaoDeMapUtil.getDistance(x+","+y, d1+","+d2);
				if(distance==-1){
					log.info("行程查询失败");
					return;
				}
				Redis.c.setex(Redis.K.ORDER_DISTANCE.to(driverId,order.getOrderNum()), EXPIRE, String.valueOf(distance));

				log.info("司机{}与乘客间的距离=================="+distance,driverId);
			}
			@Override
			public void onCancelled(SyncError arg0) {
			}

		});
	}

	/**
	 * 我的行程列表
	 */
	@Override
	public Map<String, Object> selectByDriverId(String driverId) {
		Map<String,Object> map = new HashMap<String, Object>();
		// 已完成行程list
		List<Order> noFinishRouteList = new ArrayList<Order>();
		// 未完成行程list
		List<Order> finishRouteList = new ArrayList<Order>();
		//进行中订单
		List<Order> onWayList=new ArrayList<Order>();
		
		List<Order> orderList = orderMapper.selectByDriverId(driverId);
		for (Order order : orderList) {
			int orderType=order.getOrderType();
			if(orderType==5 || orderType==7){
				if(order.getParentOrder()!=null && !order.getOrderNum().equals(order.getParentOrder())){//从列表去除拼车中子订单
					continue;
				}
				if(order.getParentOrder()!=null && order.getOrderNum().equals(order.getParentOrder())){//主单已取消
//					if(order.getOrderStatus()==Constants.ORDER_OFF){
						List<Order> oList=orderMapper.selectOrderByParentOrder(order.getParentOrder());
						if(oList.size()>0){
							for(Order o:oList){
								if(Constants.END_ROAD != o.getOrderStatus()&& o.getOrderStatus()!=Constants.ORDER_OFF && o.getParentOrder()!=o.getOrderNum()){
									onWayList.add(order);
									break;
									
								}
							}
							boolean bl=true;
							for(Order o:oList){
								int payStatus = o.getPayStatus();// 支付状态
								//有未完成拼单
								if (payStatus != Order.ST.PAID.val() && payStatus!=Order.ST.REFUNDED.val() && o.getOrderStatus()!=Constants.ORDER_OFF) {
									bl=false;
									break;
								}
							}
							if(bl==false){
									noFinishRouteList.add(order);
							}else{
								finishRouteList.add(order);
									
							}
							
						}
						continue;
//					}else{
//						
//					}
				}
//				int payStatus = order.getPayStatus();// 支付状态
//				if (payStatus == Order.ST.PAID.val() || payStatus==Order.ST.REFUNDED.val() || order.getOrderStatus()==Constants.ORDER_OFF) {
//
//					finishRouteList.add(order);
//
//				} else {// 未完成订单
//					noFinishRouteList.add(order);
//				}
				
			}else{
				int orderStatus = order.getOrderStatus();// 订单状态
				if(orderStatus!=Constants.END_ROAD && orderStatus!=Constants.ORDER_OFF){//订单未结束状态
					//进行中订单
					onWayList.add(order);
					continue;
				}
				
				int payStatus = order.getPayStatus();// 支付状态
				// 已完成订单
				if (payStatus == Order.ST.PAID.val() || payStatus==Order.ST.REFUNDED.val() || orderStatus==Constants.ORDER_OFF) {

					finishRouteList.add(order);

				} else {// 未完成订单
					noFinishRouteList.add(order);
				}
			}
		
		}
		map.put("onWayList", onWayList);
		map.put("noFinishRouteList", noFinishRouteList);
		map.put("finishRouteList", finishRouteList);

		return map;
	}

	@Override
	public int updateByDriverId(int orderStatus,String orderNum) {
		if(orderStatus==Constants.START_ROAD){
			Date startTime=new Date();
			return orderMapper.updateOrderByDriverId(startTime,orderStatus,orderNum);
		}else{
			return orderMapper.updateOrderByDriverId1(orderStatus, orderNum);
		}

	}

	@Override
	public Order selectByOrderNum(String orderNum){
		return orderMapper.selectByOrderNum(orderNum);
	}

	
	/**
	 * 取消订单
	 * @author txp
	 */
	@Override
	public DataBean cancelOrder(JSONObject fields ) {
		String orderNum = fields.getString("orderNum");
		double nullRates = fields.getDouble("nullRates");

		Order order = orderMapper.selectByOrderNum(orderNum);
		if (null==order) {
			return new DataBean(10086, new JSONObject(), "订单号错误!");
		}

		Integer i = order.getOrderStatus();

		Map<String,Object> map = new HashMap<>();
		double price = 0.0;

		long planTime = order.getPlanTime().getTime();
		long createTime = order.getCreateTime().getTime();
		
		//当订单是拼车的时候
		Boolean flag = false;
		Integer orderType = order.getOrderType();
		if (Constants.CARPOOL_NOW == orderType) {
			flag = true;
		}

		switch (i) {
		//订单状态为等待接单
		case 2:
			int a = orderMapper.updateByPrimaryKeySelective(order);
			if (a==1) {
				order.setOrderStatus(Constants.ORDER_OFF);
				orderMapper.updateByPrimaryKeySelective(order);
				map.put("cancelPrice", 0.0);
//				//司机上线
//				modelSetMapper.startGetOrder(order.getDriverId());
				if (flag) {
					orderPriceDetailMapper.deleteByOrderNum(orderNum);
				}
				return new DataBean(200, map, "取消订单成功!");
			}else{
				return new DataBean(201,  new JSONObject(), "取消订单失败!");
			}
			//订单状态为司机已接单或者到达上车点或者已派单
		case 3:
		case 4:
		case 7:
			int nullRate = 0;
			String passengerId = order.getPassengerId().toString();
			String driverId = order.getDriverId();
			//根据司机id查出car车辆信息
			Car car = carMapper.selectByDriverId(driverId);
			if (car==null) {
				return new DataBean(10010, map, "请检查司机id和车辆绑定信息!");
			}
			//查出车辆车型,1为5坐,2为7坐
			if (1==car.getSeatType()) {
				nullRate=Constants.FIVE_SEATS_CANCEL_PRICE;
			}
			if (2==car.getSeatType()) {
				nullRate=Constants.SEVEN_SEATS_CANCEL_PRICE;
			}
			long l = System.currentTimeMillis();
			Date date = order.getReceiveTime();
			long b =0;
			//订单预约时间(即时打车时间)减去下单时间小于30分钟,此订单为即时订单或者预约时间段小于30分钟,取消相对值按出发时间前30分钟算
			if (planTime-createTime>1800000) {
				planTime=planTime-1800000;
				b=l-planTime;
			}else{
				//取消订单的时间减去司机接单时间
				b  =l-date.getTime();
			}
			//当取消时间距离司机接单时间小大于一分钟
			if (b>60000) {
				price = nullRates*nullRate;
				map.put("cancelPrice", price);
				order.setOrderStatus(Constants.ORDER_OFF);
				orderMapper.updateByPrimaryKeySelective(order);
				if (flag) {
					orderPriceDetailMapper.deleteByOrderNum(orderNum);
				}
				return new DataBean(200, map, "取消订单成功!");
				//当取消时间距离司机接单时间小于一分钟
			}else{
				String key = Redis.K.PASSENGER_COUNTS.to(passengerId);
				String string = Redis.c.get(key);
				System.out.println(string+"已取消次数");
				if (string==null) {
					Redis.c.setex(Redis.K.PASSENGER_COUNTS.to(passengerId),  Redis.DAY, "1");
					string="0";
				}
				Integer in = Integer.valueOf(string);
				in++;
				System.out.println(in+"客户在司机接单后一分钟总次数(24小时内)");
				String str=in.toString();
				Redis.c.setex(Redis.K.PASSENGER_COUNTS.to(passengerId),  Redis.DAY, str);
				if (in>3) {
					price = nullRates*nullRate;
					map.put("cancelPrice", price);
					order.setOrderStatus(Constants.ORDER_OFF);
					orderMapper.updateByPrimaryKeySelective(order);
					if (flag) {
						orderPriceDetailMapper.deleteByOrderNum(orderNum);
					}
					return new DataBean(200, map, "取消订单成功!");
				}else{
					map.put("cancelPrice", 0.0);
					order.setOrderStatus(Constants.ORDER_OFF);
					orderMapper.updateByPrimaryKeySelective(order);
					if (flag) {
						orderPriceDetailMapper.deleteByOrderNum(orderNum);
					}
					return new DataBean(200, map, "取消订单成功!");
				}
			}

		default:
			return new DataBean(10086,  new JSONObject(), "订单不处于可取消状态!");
		}




	}

	@Override
	public List<Order> selectAllOrder(String driverId) {
		List<Order> orderList = orderMapper.selectByDriverId(driverId);
		List<Order> list = new ArrayList();
		for(Order order:orderList){
			if(order.getPayStatus()==Order.ST.PAID.val()){
				if(order.getOrderType()==5){
					if(order.getParentOrder()!=null && !order.getOrderNum().equals(order.getParentOrder())){//此单子订单
						 continue;
					}else if(order.getParentOrder()!=null && order.getOrderNum().equals(order.getParentOrder())){//此单为父订单
						
						
						List<Order> oList=orderMapper.selectOrderByParentOrder(order.getParentOrder());
						if(oList.size()>0){
							boolean bl=true;
							for(Order o:oList){
								int payStatus = o.getPayStatus();// 支付状态
								if (payStatus == Order.ST.PAID.val() || payStatus==Order.ST.REFUNDED.val() || o.getOrderStatus()==Constants.ORDER_OFF) {
									bl=false;

								}
							}
							if(bl==false){
								double price=0.0;
								for(Order o:oList){
									if(o.getPayStatus()==Order.ST.PAID.val()){
										price+=o.getOrderPrice();
									}
								}
								order.setOrderPrice(price);
								list.add(order);
							}
						}
						
					}		
					
				}else{//非拼车单
					list.add(order);
				}
			}
				
		}
		return list;
	}

	/**
	 * 乘客端查询可开发票金额
	 * @author txp
	 */
	@Override
	public DataBean getInvoiceMoney(Integer passengerId) {
		try {
			
			Double money = orderMapper.queryInvoiceTotalMoney(passengerId);
			if (null==money) {
				money=0.00;
			}
			
			Double money1 = invoiceMapper.queryInvoiceMoney(passengerId);
			if (null==money1) {
				money1=0.00;
			}
			double c = (new BigDecimal(Double.toString(money)).subtract(new BigDecimal(Double.toString(money1)) )).doubleValue();
			
			if (c<0) {
				return new DataBean(501, new JSONObject(), "已支付订单总金额少于已开发票金额!");
			}
			
			HashMap<String, Object> map = new HashMap<String, Object>();
			map.put("money", c);
			return new DataBean(200, map, "查询成功返回可开发票金额!");
		} catch (Exception e) {
			e.printStackTrace();
			return new DataBean(200, new JSONObject(), "服务器错误!");
		}
	}
	
	/**
	 * 乘客端开发票
	 * @author txp
	 */
	@Override
	public DataBean getInvoice(JSONObject fields) {
		
		try {
			Invoice invoice = new Invoice();
			String id = UuidUtils.getUUID();
			invoice.setId(id);
			invoice.setCreateTime(new Date());
			//发票类型(1:电子发票,2:纸质发票)
			int type = fields.getInt("type");
			invoice.setType(type);
			//客户id
			int passengerId = fields.getInt("passengerId");
			
			/*User user = userMapper.selectByTypeAndId(Constants.USER_PASSENGER, passengerId);
			User user = UserUtil.getUser(fields.getInt("passengerId"), fields.getString("token"));
			if (null==user) {
				return new DataBean(400, new JSONObject(), "乘客id错误!");
			}*/
			invoice.setPassengerId(passengerId);
			//发票金额
			double price = fields.getDouble("price");
			
			Double queryInvoiceTotalMoney = orderMapper.queryInvoiceTotalMoney(passengerId);
			if (null==queryInvoiceTotalMoney) {
				return new DataBean(401, new JSONObject(), "你没有可开发票余额!"); 
			}
			
			Double queryInvoiceMoney = invoiceMapper.queryInvoiceMoney(passengerId);
			if (null==queryInvoiceMoney) {
				queryInvoiceMoney=0.0;
			}
			
			double a = (new BigDecimal(Double.toString(orderMapper.queryInvoiceTotalMoney(passengerId))).subtract(new BigDecimal(Double.toString(queryInvoiceMoney)) )).doubleValue();
			if (price>a) {
				return new DataBean(10086, new JSONObject(), "你的可开发票金额不够!");
			}
			invoice.setInvoicePrice(price);
			//发票抬头
			String title = fields.getString("title");
			invoice.setInvoiceTitle(title);
			//纳税人识别号(选填)
			String num = fields.getString("num");
			if (StringUtil.isEmpty(num)) {
				num=null;
			}
			invoice.setTaxpayerNum(num);
			//邮箱地址
			String email = fields.getString("email");
			if (StringUtil.isEmpty(email)) {
				email=null;
			}
			invoice.setEmail(email);
			//联系电话
			String phone = fields.getString("phone");
			invoice.setPhone(phone);
			//收件人姓名
			String name = fields.getString("name");
			if (StringUtil.isEmpty(name)) {
				name=null;
			}
			invoice.setReceiveName(name);
			//收件地址
			String address = fields.getString("address");
			if (StringUtil.isEmpty(address)) {
				address=null;
			}
			invoice.setReceiveAddress(address);
			
			int i = invoiceMapper.insertSelective(invoice);
			
			if (i==1) {
				return new DataBean(200, new JSONObject(), "开具发票成功,请耐心等待!");
			} else {
				return new DataBean(400, new JSONObject(), "开具发票失败!");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			return new DataBean(501, new JSONObject(), "服务器异常,开具发票失败!");
		}
		
		
	}

	@Override
	public List<Order> selectOrderByParentOrder(String orderNum) {
		return orderMapper.selectOrderByParentOrder(orderNum);
	}

	@Override
	public int queryDriverOrderNumber(String driverId) {
		return orderMapper.queryDriverOrderNumber(driverId);
	}
	
	@Override
	public int updateByOrderNum(String orderNum, Date endTime, int orderStatus,
			double orderPrice, int payStatus) {
		return orderMapper.updateByOrderNum(orderNum, new Date(),
				Constants.END_ROAD, orderPrice,Order.ST.CREATED.val());
	}

	@Override
	public DataBean getPayStatus(String orderNo) {
		//根据订单号查询状态和支付状态
		Order order = orderMapper.selectByOrderNum(orderNo);
		if (null==order) {
			return new DataBean(400, new JSONObject(), "订单号错误!");
		}
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("payStatus", order.getPayStatus());
		map.put("orderStatus", order.getOrderStatus());
		return new DataBean(200, map, "查询成功!");
	}

	@Override
	public DataBeanEcar getByPager(Pager pager) {
		List<HashMap<String, Object>> list = orderMapper.selectByPager(pager);
		if (0==list.size()) {
			return new DataBeanEcar(200, new JSONObject(), "无该记录", 0, 0);
		}
		int totalNum = Integer.parseInt(list.get(0).get("number").toString());
		System.out.println(totalNum);
		return new DataBeanEcar(200, list, "调用返回成功", totalNum, totalNum/pager.getPageSize());
	}
}
